﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using AutoFacWrapper;
using Senparc.Weixin;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.AdvancedAPIs.OAuth;
using Senparc.Weixin.MP.Helpers;
using Senparc.Weixin.MP.TenPayLib;
using Senparc.Weixin.MP.TenPayLibV3;
using ZL.WeChatCard.Entity;
using ZL.WeChatCard.Entity.EasyQuery;
using ZL.WeChatCard.Entity.EasyUse;
using ZL.WeChatCard.Entity.ViewModel;
using ZL.WeChatCard.Service;
using ZL.WeChatCard.Service.InterFace;
using ZLWeb.WebApiEntity.EasyUse;
using RequestHandler = Senparc.Weixin.MP.TenPayLibV3.RequestHandler;
using ResponseHandler = Senparc.Weixin.MP.TenPayLibV3.ResponseHandler;
using Result = ZL.WeChatCard.Entity.Result;

namespace ZLWeChatCard.Controllers
{
    public class ChargeController : BaseController
    {
        public ZzinfocsResponse ChargeInfo
        {
            get
            {
                var cservic = ClassFactory.GetInstance<IChargeService>();
                return cservic.GetChargeInfo();
            }
        }

        public ActionResult Index()
        {
            var pservice = ClassFactory.GetInstance<IPaymentService>();
            AccInfo item = pservice.GetNo(OpenID);
            if (item == null)
            {
                return Redirect("~/Payment/Regesiter?act=Index&&contro=Charge");
            }
            if(!item.IsSuccess) return Redirect("~/Payment/Regesiter?act=Index&&contro=Charge");
            return View("Charge", ChargeInfo.Zzinfocss);
        }

        private static TenPayV3Info _tenPayV3Info;

        /// <summary>
        /// 获取配置信息
        /// </summary>
        public static TenPayV3Info TenPayV3Info
        {
            get
            {
                if (_tenPayV3Info == null)
                {
                    _tenPayV3Info =
                        TenPayV3InfoCollection.Data[System.Configuration.ConfigurationManager.AppSettings["TenPayV3_MchId"]];
                }
                return _tenPayV3Info;
            }
        }

        public ActionResult Pay(string czxk)
        {
            Zzinfocs SelectZzinfocs = ChargeInfo.Zzinfocss.FirstOrDefault(tr => tr.czxk.ToString() == czxk);
            if (SelectZzinfocs == null) return null;
            var pservice = ClassFactory.GetInstance<IPaymentService>();
            AccInfo item = pservice.GetNo(OpenID);
            var accOprInfoService = ClassFactory.GetInstance<IEasyQueryService>();

            var info = accOprInfoService.GetBalanceChanges(OpenID);
            var infos = new List<AccOprInfo>();
            if (info != null)
            {
                infos.AddRange(info.AccOprInfos);
            }
            PayModel pay=new PayModel() { WalletInfo= infos, selectzinfoc = SelectZzinfocs , Dycardno= item.Dycardno};
            return View("Pay", pay);
        }

        public ActionResult JsApi(string czxk, string Dycardno)
        {
            var returnUrl = string.Format("http://{0}/Charge/WeiXinPay", Request.Url.Host);
            var state = czxk + "|"+ Dycardno;
            var url = OAuthApi.GetAuthorizeUrl(TenPayV3Info.AppId, returnUrl, state, OAuthScope.snsapi_base);
            return Redirect(url);
        }
        private IChargeService cservic = ClassFactory.GetInstance<IChargeService>();
        //public ActionResult WeiXinPay(string code, string state)
        public ActionResult WeiXinPay(string code, string state)
        {
            if (string.IsNullOrEmpty(code)|| string.IsNullOrEmpty(state))
            {
                return Content("拒绝了授权！");
            }
            if (!state.Contains("|"))
            {
                //这里的state其实是会暴露给客户端的，验证能力很弱，这里只是演示一下
                //实际上可以存任何想传递的数据，比如用户ID，并且需要结合例如下面的Session["OAuthAccessToken"]进行验证
                return Content("验证失败！请从正规途径进入！");
            }
            string openIdResultopenid = string.Empty;
            try
            {
                var openIdResult = OAuthApi.GetAccessToken(TenPayV3Info.AppId, TenPayV3Info.AppSecret, code);
                 openIdResultopenid = openIdResult.openid;
                //if (Session["OAuthAccessTokenResult"] == null) return Content("验证失败！请从正规途径进入！1001");
                //var openIdResult = Session["OAuthAccessTokenResult"] as OAuthAccessTokenResult;
                if (openIdResult.errcode != ReturnCode.请求成功)
                {
                    return Content("错误：" + openIdResult.errmsg);
                }
            }
            catch (Exception)
            {
                return Redirect("~/Charge/Index");
            }
         
            string[] param=state.Split('|');
            string czxk = param[0];
            string Dycardno = param[1];
            AccCzResponse charge=new AccCzResponse();
            TranData pay =new TranData();
            //通过，用code换取access_token
            var item = ChargeInfo.Zzinfocss.FirstOrDefault(tr => tr.czxk.ToString() == czxk);
            if(item==null) return Content("验证失败！请从正规途径进入！1001");
            try
            {
                ThrywInfo ywInfo = new ThrywInfo();
                ywInfo.cardno = Dycardno;
                ywInfo.ctype = 5;
                ywInfo.oprczxj = item.czxk;
                ywInfo.oprczzz = item.czzsz;
                ywInfo.oprywwindow = "充值";
                ywInfo.oprsummary = string.Format("充{0},抵{1}", item.czxk, item.czzsz);
                ywInfo.pno = new dpno();
                charge = cservic.PreCharge(ywInfo);
                if (charge == null) return View("WeiChatPay");
                if (!charge.IsSuccess) return View("WeiChatPay");
                pay.pno = charge.pno.pno;
                pay.pnopwd = charge.pno.pnopwd;
                Thrpaylog thrpaylog = new Thrpaylog();
                thrpaylog.payway = 1;
                thrpaylog.xlog = new Wxlog();
                thrpaylog.xlog.tlglywje = item.czxk;
                thrpaylog.xlog.tlglpno = charge.pno.pno;
                thrpaylog.xlog.tlglpnopwd = charge.pno.pnopwd;
                thrpaylog.xlog.tlglywjmmc = "充值";
                thrpaylog.xlog.tlglywxx = string.Format("充{0},抵{1}", item.czxk, item.czzsz);
                Thrpaylog plog = cservic.ChargeNewSave(thrpaylog);
                string timeStamp = "";
                string nonceStr = "";
                string paySign = "";
            
                string sp_billno = Request["order_no"];
                //当前时间 yyyyMMdd
                string date = DateTime.Now.ToString("yyyyMMdd");

                if (null == sp_billno)
                {
                    //生成订单10位序列号，此处用时间和随机数生成，商户根据自己调整，保证唯一
                    sp_billno = DateTime.Now.ToString("HHmmss") + TenPayV3Util.BuildRandomStr(28);
                }
                else
                {
                    sp_billno = Request["order_no"].ToString();
                }

                //创建支付应答对象
                RequestHandler packageReqHandler = new RequestHandler(null);
                //初始化
                packageReqHandler.Init();

                timeStamp = TenPayV3Util.GetTimestamp();
                nonceStr = TenPayV3Util.GetNoncestr();

                //设置package订单参数
                packageReqHandler.SetParameter("appid", TenPayV3Info.AppId); //公众账号ID
                packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId); //商户号
                packageReqHandler.SetParameter("nonce_str", nonceStr); //随机字符串
                packageReqHandler.SetParameter("body", string.Format("充{0},抵{1}", item.czxk, item.czzsz));
                packageReqHandler.SetParameter("out_trade_no", sp_billno); //商家订单号
                packageReqHandler.SetParameter("total_fee", "1"); //商品金额,以分为单位(money * 100).ToString()
                packageReqHandler.SetParameter("spbill_create_ip", Request.UserHostAddress); //用户的公网ip，不是商户服务器IP
                packageReqHandler.SetParameter("notify_url",
                    string.Format("https://{0}/Charge/{1}", Request.Url.Host, TenPayV3Info.TenPayV3Notify));
                    //接收财付通通知的URL
                packageReqHandler.SetParameter("trade_type", TenPayV3Type.JSAPI.ToString()); //交易类型
                packageReqHandler.SetParameter("openid", openIdResultopenid); //用户的openId
                packageReqHandler.SetParameter("attach", string.Format("{0}|{1}|{2}", charge.pno.pno, charge.pno.pnopwd, plog.xlog.tllsh));
                string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
                packageReqHandler.SetParameter("sign", sign); //签名

                string data = packageReqHandler.ParseXML();

                var result = TenPayV3.Unifiedorder(data);
                var res = XDocument.Parse(result);
                string prepayId = res.Element("xml").Element("prepay_id").Value;

                //设置支付参数
                RequestHandler paySignReqHandler = new RequestHandler(null);
                paySignReqHandler.SetParameter("appId", TenPayV3Info.AppId);
                paySignReqHandler.SetParameter("timeStamp", timeStamp);
                paySignReqHandler.SetParameter("nonceStr", nonceStr);
                paySignReqHandler.SetParameter("package", string.Format("prepay_id={0}", prepayId));
                paySignReqHandler.SetParameter("signType", "MD5");
                paySign = paySignReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
                ViewData["appId"] = TenPayV3Info.AppId;
                ViewData["timeStamp"] = timeStamp;
                ViewData["nonceStr"] = nonceStr;
                ViewData["package"] = string.Format("prepay_id={0}", prepayId);
                ViewData["paySign"] = paySign;

            }
            catch (Exception exception)
            {
                try
                {
                    QueryParam qp = new QueryParam();
                    qp.pno = charge.pno.pno;
                    qp.pnopwd = charge.pno.pnopwd;
                    qp.payway = 1;
                    ResponseResultInfo ResultInfo = cservic.ChargeCancel(charge.pno.pno, charge.pno.pnopwd);
                }
                catch (Exception ex)
                {
                    return View("WeiChatPay", pay);
                }
            }
            return View("WeiChatPay", pay);
        }

        public ActionResult Success()
        {
            return View("Success");
        }

        public ActionResult Query(string pno,string pnopwd)
        {
            try
            {
                int count = 1;
                while (true)
                {
                    QueryParam qpm = new QueryParam();
                    qpm.pno = pno;
                    qpm.pnopwd = pnopwd;
                    qpm.payway = 1;
                    Result res1 = cservic.ChargeResultQuery(qpm);
                    if (res1 != null)
                        return Content(res1.result.ToString());
                    if (count == 0) break;
                    Thread.Sleep(1000);
                    count--;
                }
            }
            catch (Exception ex)
            {
            }
            return Content("0");
        }

        public ActionResult CauseProblem(string pno, string pnopwd)
        {
            QueryParam qp = new QueryParam();
            qp.pno = pno;
            qp.pnopwd = pnopwd;
            qp.payway = 1;
            ResponseResultInfo ResultInfo = cservic.ChargeCancel(qp.pno, qp.pnopwd);
            if (ResultInfo == null)
            {
                return Content("");
            }
            return Content("");
        }

        public ActionResult Send()
        {
            try
            {
                ResponseHandler resHandler = new ResponseHandler(null);
                resHandler.SetKey(TenPayV3Info.Key);
                if (!resHandler.IsTenpaySign()) return null;
                string attach = resHandler.GetParameter("attach");
                if (!attach.Contains("|")) return null;
                string[] paystr = attach.Split('|');
                if (paystr.Count() != 3)
                {
                    return null;
                }
                string return_code = resHandler.GetParameter("return_code");
                string return_msg = resHandler.GetParameter("return_msg");
                string transaction_id = resHandler.GetParameter("transaction_id");
                string bank_type = resHandler.GetParameter("bank_type");
                string xml = string.Format(@"<xml>
           <return_code><![CDATA[{0}]]></return_code>
           <return_msg><![CDATA[{1}]]></return_msg>
        </xml>", return_code, return_msg);
                QueryParam qpm = new QueryParam();
                qpm.pno = paystr[0];
                qpm.pnopwd = paystr[1];
                qpm.payway = 1;
                Result res1 = cservic.ChargeResultQuery(qpm);
                if (res1.result == 1)
                {
                    return Content(xml, "text/xml");
                }
                //验证请求是否从微信发过来（安全）
                Thrpaylog modlog = new Thrpaylog();
                modlog.payway = 1;
                modlog.xlog = new Wxlog();
                modlog.xlog.tlqyh = TenPayV3Info.AppId;
                modlog.xlog.tljylsh = transaction_id;
                modlog.xlog.tlyhbj = OpenID;
                modlog.xlog.tlsjyxbj = 1;
                modlog.xlog.tlgzzhbj = 1;
                modlog.xlog.tlsjcxzffhwj = return_msg;
                modlog.xlog.tlsjzfsm = xml;
                modlog.xlog.tlfkyh = bank_type;
                modlog.paysno = paystr[2];
                modlog.xlog.tllsh = paystr[2];
                if (return_code.ToUpper() == "SUCCESS")
                {
                    modlog.xlog.tlsjzfbj = 1;
                }
                else
                {
                    modlog.xlog.tlsjzfbj = 2;
                }
                Thrpaylog plog1 = cservic.ChargeModifySave(modlog);
                return Content(xml, "text/xml");
            }
            catch (Exception)
            {
                return null;
            }
            return null;

        }

        //public ActionResult Pay1(int czgsid)
        //{
        //    var cservic = ClassFactory.GetInstance<IChargeService>();
        //    var ChargeInfo = cservic.GetChargeInfo();
        //    var item = ChargeInfo.Zzinfocss.FirstOrDefault(tr => tr.czgsid == czgsid);
        //    if (item == null) return null;

        //    var pservice = ClassFactory.GetInstance<IPaymentService>();
        //    AccInfoResponse ain = pservice.GetAllAccInfo(OpenID);
        //    cservic = ClassFactory.GetInstance<IChargeService>();
        //    ThrywInfo ywInfo = new ThrywInfo();
        //    ywInfo.cardno = ain.AccInfo.Dycardno;
        //    ywInfo.ctype = 5;
        //    ywInfo.oprczxj = item.czxk;
        //    ywInfo.oprczzz = item.czzsz;
        //    ywInfo.oprywwindow = "充值";
        //    ywInfo.pno = new dpno();
        //    var charge = cservic.PreCharge(ywInfo);

        //    Thrpaylog thrpaylog = new Thrpaylog();
        //    thrpaylog.payway = 1;
        //    thrpaylog.xlog = new Wxlog();
        //    thrpaylog.xlog.tlglywje = item.czxk;
        //    thrpaylog.xlog.tlglpno = charge.pno.pno;
        //    thrpaylog.xlog.tlglpnopwd = charge.pno.pnopwd;
        //    thrpaylog.xlog.tlglywjmmc = "充值";
        //    Thrpaylog plog = cservic.ChargeNewSave(thrpaylog);

        //    Thrpaylog modlog = new Thrpaylog();
        //    modlog.payway = 1;
        //    modlog.xlog = new Wxlog();
        //    modlog.xlog.tlfkyh = "test1";
        //    modlog.xlog.tlyhbj = OpenID;
        //    modlog.xlog.tlfkyh = "工商银行";
        //    modlog.xlog.tlsjzfbj = 1;
        //    modlog.paysno = plog.xlog.tllsh;
        //    modlog.xlog.tllsh = plog.xlog.tllsh;
        //    Thrpaylog plog1 = cservic.ChargeModifySave(modlog);

        //    QueryParam qp = new QueryParam();
        //    qp.pno = charge.pno.pno;
        //    qp.pnopwd = charge.pno.pnopwd;
        //    qp.payway = 1;
        //    Result ss = cservic.ChargeResultQuery(qp);
        //    //QueryParam qp=new QueryParam();
        //    //qp.pno = charge.pno.pno;
        //    //qp.pnopwd = charge.pno.pnopwd;
        //    //qp.payway = 1;
        //    //ResponseResultInfo ResultInfo= cservic.ChargeCancel(charge.pno.pno, charge.pno.pnopwd);
        //    return View("Pay", ain.WalletInfo);
        //}



        //public ActionResult PayNotifyUrl1()
        //{

        //    ResponseHandler resHandler = new ResponseHandler(null);
        //    resHandler.Init();
        //    resHandler.SetKey(TenPayInfo.Key, TenPayInfo.AppKey);

        //    string message;

        //    //判断签名
        //    if (resHandler.IsTenpaySign())
        //    {
        //        if (resHandler.IsWXsign())
        //        {
        //            //商户在收到后台通知后根据通知ID向财付通发起验证确认，采用后台系统调用交互模式
        //            string notify_id = resHandler.GetParameter("notify_id");
        //            //取结果参数做业务处理
        //            string out_trade_no = resHandler.GetParameter("out_trade_no");
        //            //财付通订单号
        //            string transaction_id = resHandler.GetParameter("transaction_id");
        //            //金额,以分为单位
        //            string total_fee = resHandler.GetParameter("total_fee");
        //            //如果有使用折扣券，discount有值，total_fee+discount=原请求的total_fee
        //            string discount = resHandler.GetParameter("discount");
        //            //支付结果
        //            string trade_state = resHandler.GetParameter("trade_state");

        //            string payMessage = null;

        //            //即时到账
        //            if ("0".Equals(trade_state))
        //            {
        //                //------------------------------
        //                //处理业务开始
        //                //------------------------------

        //                //处理数据库逻辑
        //                //注意交易单不要重复处理
        //                //注意判断返回金额

        //                //------------------------------
        //                //处理业务完毕
        //                //------------------------------

        //                //给财付通系统发送成功信息，财付通系统收到此结果后不再进行后续通知
        //                payMessage = "success 后台通知成功";
        //            }
        //            else
        //            {
        //                payMessage = "支付失败";
        //            }
        //            ViewData["payMessage"] = payMessage;
        //            //回复服务器处理成功
        //            message = "success";
        //        }

        //        else
        //        {//SHA1签名失败
        //            message = "SHA1签名失败" + resHandler.GetDebugInfo();
        //        }
        //    }

        //    else
        //    {//md5签名失败
        //        message = "md5签名失败" + resHandler.GetDebugInfo();
        //    }
        //    ViewData["message"] = message;

        //    return Content("Success");
        //}



    }
}